//
//  RenrenLoginViewController.m
//  huipai_3
//
//  Created by tan xi on 11-9-9.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#import "RenrenLoginViewController.h"

static NSString* kWidgetURL=@"http://widget.renren.com/callback.html";
static NSString* kWidgetDialogURL=@"//widget.renren.com/dialog";

@implementation RenrenLoginViewController

@synthesize delegate = _delegate, params = _params;

- (id)initWithURL: (NSString *) loadingURL
           params: (NSMutableDictionary *) tParams
         delegate: (id <RRViewControllerDelegate>) tDelegate
{
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        // Custom initialization
        _orientation = UIDeviceOrientationUnknown;
        _showingKeyboard = NO;
        
        _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 44, 320, 416)];
        _webView.delegate = self;
        [self.view addSubview:_webView];
        
        _spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:
                    UIActivityIndicatorViewStyleWhiteLarge];
        _spinner.autoresizingMask =
        UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin
        | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
        [self.view addSubview:_spinner];
        _modalBackgroundView = [[UIView alloc] init];
        _serverURL = [loadingURL retain];
        _params = [tParams retain];
        _delegate = tDelegate;
        
        UINavigationBar *_navBar = [[[UINavigationBar alloc] initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, 44)] autorelease];
        UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle: NSLocalizedString(@"人人网", nil)] autorelease];
        UIBarButtonItem *backBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];
        navItem.leftBarButtonItem = [backBtn autorelease];
        
        [_navBar pushNavigationItem: navItem animated: NO];
        [self.view addSubview:_navBar];
        
        [self load];
    }
    return self;
}

- (void)dealloc
{
    _webView.delegate = nil;
    [_webView release];
    _webView = nil;
    [_params release];
    [_serverURL release];
    [_spinner release];
    [_loadingURL release];
    _delegate = nil;
    [_modalBackgroundView release];
    [super  dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
}
*/

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - web view delegate

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
 navigationType:(UIWebViewNavigationType)navigationType {
	_spinner.hidden = NO;
    [_spinner startAnimating];
    NSURL* url = request.URL;
	NSString *errorReason=nil;
	NSString *query = [url fragment];
	if (!query) {
		query = [url query];
	}
	NSDictionary *params = [self parseURLParams:query];
	NSString *accessToken = [params valueForKey:@"access_token"];
	NSString *error_desc = [params valueForKey:@"error_description"];
	errorReason = [params valueForKey:@"error"];
	if (errorReason) {
		[self errormsg:error_desc];
		[self dialogDidCancel:url];
	}
	
	NSString *q = [url absoluteString];
	NSString* isOk=[q hasPrefix:kWidgetURL]?@"yes":@"no";
	if([isOk isEqualToString:@"yes"]&&accessToken) {
		[self dialogDidSucceed:url];
	}
    
	if (navigationType == UIWebViewNavigationTypeLinkClicked)//点击链接  
	{
        BOOL userDidCancel = ((errorReason && [errorReason isEqualToString:@"login_denied"])||
                              [errorReason isEqualToString:@"access_denied"]);
        if(userDidCancel){
            [self dialogDidCancel:url];
        }else {
            [[UIApplication sharedApplication] openURL:request.URL];
        }
        return NO;
	}
	
	if (navigationType==UIWebViewNavigationTypeFormSubmitted) {//提交表单
		NSString *state=[params valueForKey:@"flag"];
		if ((state && [state isEqualToString:@"success"])||accessToken) {
			[self dialogDidSucceed:url];
		}
	}
    return YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [_spinner stopAnimating];
    _spinner.hidden = YES;
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    // 102 == WebKitErrorFrameLoadInterruptedByPolicyChange
    if (!([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102)) {
        [self dismissWithError:error animated:YES];
    }
}

#pragma mark - my method 

- (void)dismissWithSuccess:(BOOL)success animated:(BOOL)animated {
    if (success) {
        if ([_delegate respondsToSelector:@selector(loginViewDidComplete:)]) {
            [_delegate loginViewDidComplete:self];
        }
    } else {
        if ([_delegate respondsToSelector:@selector(loginViewDidNotComplete:)]) {
            [_delegate loginViewDidNotComplete:self];
        }
    }
    
    [self dismissModalViewControllerAnimated:animated];
    [_loadingURL release];
    _loadingURL = nil;
}

- (void)dialogDidSucceed:(NSURL *)url {
	NSString *q = [url absoluteString];
	NSString* isOk=[url.resourceSpecifier hasPrefix:kWidgetDialogURL]?@"yes":@"no";
	if([isOk isEqualToString:@"no"]) {
        NSString *token = [self getStringFromUrl:q needle:@"access_token="];
        NSString *expTime = [self getStringFromUrl:q needle:@"expires_in="];
        NSDate *expirationDate =nil;
        if (expTime != nil) {
            int expVal = [expTime intValue];
            if (expVal == 0) {
                expirationDate = [NSDate distantFuture];
            } else {
                expirationDate = [NSDate dateWithTimeIntervalSinceNow:expVal];
            } 
        } 
        if ((token == (NSString *) [NSNull null]) || (token.length == 0)) {
            [self dialogDidCancel:url];
            [self dismissWithSuccess:NO animated:YES];
        } else {
            if ([_delegate respondsToSelector:@selector(rrLoginViewLogin:expirationDate:)]) {
                [_delegate rrLoginViewLogin:token expirationDate:expirationDate];
            }
            [self dismissWithSuccess:YES animated:YES];
        }
    }
    NSString *flag = [self getStringFromUrl:q needle:@"flag="];	
    if ([flag isEqualToString:@"success"]) {
        NSString *query = [url fragment];
        if (!query) {
            query = [url query];
        }
        NSDictionary *params = [self parseURLParams:query];
        if ([_delegate respondsToSelector:@selector(widgetloginViewCompleteWithDict:)]) {
            [_delegate widgetloginViewCompleteWithDict:params];
        }
    }
    if ([_delegate respondsToSelector:@selector(loginViewCompleteWithUrl:)]) {
        [_delegate loginViewCompleteWithUrl:url];
    }
    [self dismissWithSuccess:YES animated:YES];
}

- (void)dialogDidCancel:(NSURL *)url {
    if ([_delegate respondsToSelector:@selector(loginViewDidNotCompleteWithUrl:)]) {
        [_delegate loginViewDidNotCompleteWithUrl:url];
    }
    [self dismissWithSuccess:NO animated:YES];
}

- (NSURL*)generateURL:(NSString*)baseURL params:(NSDictionary*)params {
    if (params) {
        NSMutableArray* pairs = [NSMutableArray array];
        for (NSString* key in params.keyEnumerator) {
            NSString* value = [params objectForKey:key];
            NSString* escaped_value = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                                                  NULL, /* allocator */
                                                  (CFStringRef)value,
                                                  NULL, /* charactersToLeaveUnescaped */
                                                  (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                  kCFStringEncodingUTF8);
            
            [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, escaped_value]];
            [escaped_value release];
        }
        
        NSString* query = [pairs componentsJoinedByString:@"&"];
        NSString* url = [NSString stringWithFormat:@"%@?%@", baseURL, query];
        return [NSURL URLWithString:url];
    } else {
        return [NSURL URLWithString:baseURL];
    }
}

- (void)load {
    [self loadURL:_serverURL get:_params];
}

- (void)loadURL:(NSString*)url get:(NSDictionary*)getParams {
    [_loadingURL release];
    _loadingURL = [[self generateURL:url params:getParams] retain];	
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:_loadingURL];
    [_webView loadRequest:request];
}

-(void) errormsg:(NSString*) errorReason{
	if (errorReason) {
		if ([errorReason isEqualToString:@"expired_token"]) {
			NSLog(@"当前Token已过期。");
		}else if ([errorReason isEqualToString:@"invalid_request"]) {
			NSLog(@"请求缺少某个必需参数，包含一个不支持的参数或参数值，或者格式不正确。");
		}else if ([errorReason isEqualToString:@"invalid_client"]) {
			NSLog(@"无效的client_id");
		}else if ([errorReason isEqualToString:@"unauthorized_client"]) {
			NSLog(@"客户端没有权限申请该“response_type”对应的Access Grant。");
		}else if ([errorReason isEqualToString:@"access_denied"]) {
			NSLog(@"用户或授权服务器拒绝了请求。");
		}else if ([errorReason isEqualToString:@"unsupported_response_type"]) {
			NSLog(@"response_type 不为授权服务器所支持。");
		}else if ([errorReason isEqualToString:@"invalid_scope"]) {
			NSLog(@"请求的 scope 参数是无效的、未知的，或格式不正确的。");
		}else if ([errorReason isEqualToString:@"invalid_grant"]) {
			NSLog(@"提供的Access Grant是无效的、过期的或已撤销的");
		}else if ([errorReason isEqualToString:@"unsupported_grant_type"]) {
			NSLog(@"grant_type 不为授权服务器所支持。");
		}else {
			NSLog(@"未知的网络错误,关闭或是其它原因");
		}
	}
}

- (void)dismissWithError:(NSError*)error animated:(BOOL)animated {
    if ([_delegate respondsToSelector:@selector(loginView:didFailWithError:)]) {
        [_delegate loginView:self didFailWithError:error];
    }
    
    [self dismissModalViewControllerAnimated:animated];
} 

- (NSDictionary*)parseURLParams:(NSString *)query {
    @try {
        NSArray *pairs = [query componentsSeparatedByString:@"&"];
        NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease];
        for (NSString *pair in pairs) {
            NSArray *kv = [pair componentsSeparatedByString:@"="];
            NSString *val =
            [[kv objectAtIndex:1]
             stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            
            [params setObject:val forKey:[kv objectAtIndex:0]];
        }
        return params;
    }
    @catch (NSException *exception) {
        NSLog(@"%@" , exception);
    }
    return nil;
	
}

- (NSString *) getStringFromUrl: (NSString*) url needle:(NSString *) needle {
    NSString * str = nil;
    NSRange start = [url rangeOfString:needle];
    if (start.location != NSNotFound) {
        NSRange end = [[url substringFromIndex:start.location+start.length] rangeOfString:@"&"];
        NSUInteger offset = start.location+start.length;
        str = end.location == NSNotFound
        ? [url substringFromIndex:offset]
        : [url substringWithRange:NSMakeRange(offset, end.location)];
        str = [str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    
    return str;
}

- (void)cancel:(id)sender
{
    [self dismissWithError:[NSError errorWithDomain:@"用户取消" code:342 userInfo:nil] animated:YES];
}

@end
